package handlers

import (
	"encoding/json"
	"fmt"
	"net/http"
	"time"

	"github.com/golang-jwt/jwt/v5"
	"github.com/gorilla/mux"
	"skedule-backend/auth"
	"skedule-backend/utils"
)

// AuthConfig 认证配置
type AuthConfig struct {
	Username   string
	Password   string
	JWTSecret  string
	TokenTTL   time.Duration
}

// LoginRequest 登录请求
type LoginRequest struct {
	Username string `json:"username"`
	Password string `json:"password"`
}

// ChangePasswordRequest 修改密码请求
type ChangePasswordRequest struct {
	OldPassword string `json:"oldPassword"`
	NewPassword string `json:"newPassword"`
}

// LoginResponse 登录响应
type LoginResponse struct {
	Success bool   `json:"success"`
	Token   string `json:"token,omitempty"`
	Message string `json:"message,omitempty"`
	Salt    string `json:"salt,omitempty"`
}

// AuthHandler 认证处理器
type AuthHandler struct {
	config *AuthConfig
}

// NewAuthHandler 创建认证处理器
func NewAuthHandler(config *AuthConfig) *AuthHandler {
	return &AuthHandler{config: config}
}

// Login 登录处理
func (h *AuthHandler) Login(w http.ResponseWriter, r *http.Request) {
	var req LoginRequest
	if err := json.NewDecoder(r.Body).Decode(&req); err != nil {
		Error(w, CodeBadRequest, utils.T("auth.request.invalid"))
		return
	}

	// 验证用户名密码
	if !auth.ValidateCredentials(req.Username, req.Password) {
		ErrorWithData(w, CodeUnauthorized, utils.T("auth.credentials.invalid"), map[string]interface{}{
			"salt": auth.GetSalt(),
		})
		return
	}

	// 生成JWT token
	token := jwt.New(jwt.SigningMethodHS256)
	claims := token.Claims.(jwt.MapClaims)
	claims["username"] = req.Username
	claims["exp"] = time.Now().Add(h.config.TokenTTL).Unix()

	tokenString, err := token.SignedString([]byte(h.config.JWTSecret))
	if err != nil {
		Error(w, CodeInternalError, utils.T("auth.token.generate.failed"))
		return
	}

	SuccessWithMsg(w, utils.T("auth.login.success"), map[string]interface{}{
		"token": tokenString,
	})
}

// ChangePassword 修改密码处理
func (h *AuthHandler) ChangePassword(w http.ResponseWriter, r *http.Request) {
	var req ChangePasswordRequest
	if err := json.NewDecoder(r.Body).Decode(&req); err != nil {
		Error(w, CodeBadRequest, utils.T("auth.request.invalid"))
		return
	}

	// 验证原密码
	if !auth.ValidateCredentials(h.config.Username, req.OldPassword) {
		Error(w, CodeUnauthorized, utils.T("auth.password.old.incorrect"))
		return
	}

	// 更新密码
	if err := auth.UpdatePassword(h.config.Username, req.NewPassword); err != nil {
		Error(w, CodeInternalError, fmt.Sprintf(utils.T("auth.password.update.failed"), err.Error()))
		return
	}

	// 更新内存中的配置
	h.config.Password = req.NewPassword

	SuccessWithMsg(w, utils.T("auth.password.change.success"), nil)
}

// GetSaltHandler 获取盐值的处理器
func GetSaltHandler() http.HandlerFunc {
	return func(w http.ResponseWriter, r *http.Request) {
		Success(w, map[string]string{
			"salt": auth.GetSalt(),
		})
	}
}

// SetupAuthRoutes 设置认证路由（不需要JWT）
func SetupAuthRoutes(router *mux.Router, authHandler *AuthHandler) {
	authRouter := router.PathPrefix("/auth").Subrouter()
	authRouter.HandleFunc("/salt", GetSaltHandler()).Methods("GET")
	authRouter.HandleFunc("/login", authHandler.Login).Methods("POST")
}

// SetupProtectedAuthRoutes 设置需要认证的认证路由
func SetupProtectedAuthRoutes(router *mux.Router, authHandler *AuthHandler) {
	authRouter := router.PathPrefix("/auth").Subrouter()
	authRouter.HandleFunc("/change-password", authHandler.ChangePassword).Methods("POST")
} 